package com.ruoyi.system.service.manager.impl;

import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.ConfigType;
import com.alibaba.nacos.api.exception.NacosException;
import com.ruoyi.common.utils.yaml.YamlEditUtil;
import com.ruoyi.common.utils.yaml.YamlUtil;
import com.ruoyi.system.service.manager.INacosConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;

/**
 * nacos工具
 *
 * @author Hack2003
 * @date 2024/4/1 14:52
 **/
@Service
@Slf4j
public class NacosConfigServiceImpl implements INacosConfigService {
    @Autowired
    private ConfigService configService;

    /**
     * 更新Nacos中的配置内容
     *
     * @param dataId  配置数据的唯一ID
     * @param group   配置所属的组别，默认为 DEFAULT_GROUP
     * @param content 新的配置内容
     * @throws NacosException 如果更新过程中发生错误
     */
    public boolean updateConfig(String dataId, String group, String content) throws NacosException {
        return configService.publishConfig(dataId, group, content);
    }


    /**
     * 更新Nacos中YAML配置文件中的某个属性值
     *
     * @param dataId       配置数据的唯一ID
     * @param group        配置所属的组别，默认为 DEFAULT_GROUP
     * @param propertyName 要修改的属性名称
     * @param newValue     新的属性值
     * @throws NacosException 更新过程中的错误
     */
    public void updatePropertyInYamlConfig(String dataId, String group, String propertyName, String newValue) throws NacosException {
        try {
            if (Objects.isNull(configService)) {
                throw new NacosException(-3, "获取不到configService属性！");
            }

            // 获取当前配置内容
            String currentConfigContent = configService.getConfig(dataId, group, 35000);
            if (Objects.isNull(currentConfigContent)) {
                throw new NacosException(-2, "nacos解释不了dataId:" + dataId + "对应的内容！");
            }
            System.out.println("原始文件内容：==========\n" + currentConfigContent);
            String updatedConfigContent = YamlEditUtil.replaceValueInLoadedYaml(currentConfigContent, "name", "xxx");
            System.out.println("修改后内容:==========\n" + updatedConfigContent);
            try {
                configService.publishConfig(dataId, group, updatedConfigContent, ConfigType.YAML.getType());
            } catch (Exception e) {
                e.printStackTrace();
                throw new NacosException(-5, "更新配置失败！");
            }
            log.info("成功更新属性【{}】的值【{}】", propertyName, newValue);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("更新属性 {} 失败，原因：{}", propertyName, e.getMessage());
            throw new NacosException(-1, "更新属性失败，请查看日志详情");
        }
    }

    /**
     * 递归更新嵌套Map中的属性值
     *
     * @param map      当前层级的Map
     * @param path     属性路径
     * @param newValue 新的属性值
     */
    private void updateNestedProperty(Map<String, Object> map, String path, String newValue) {
        String[] keys = path.split("\\.");
        if (keys.length > 1) {
            String firstKey = keys[0];
            Map<String, Object> nestedMap = (Map<String, Object>) map.computeIfAbsent(firstKey, k -> new LinkedHashMap<>());
            updateNestedProperty(nestedMap, String.join(".", Arrays.copyOfRange(keys, 1, keys.length)), newValue);
        } else {
            map.put(keys[0], newValue);
        }
    }
}
